package com.boot.adminservice.map.service.strategy;

import com.boot.adminapi.map.constants.MapConstants;
import com.boot.adminservice.map.domain.dto.SysRegionDTO;
import com.boot.commoncache.utils.CacheUtil;
import com.boot.commonredis.service.RedisService;
import com.fasterxml.jackson.core.type.TypeReference;
import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 获取城市列表具体策略:先查两级缓存(本地缓存+Redis)，未命中再从数据库查询策略
 */
@Component("fromL2CacheStrategy")
public class FromL2CacheStrategy implements GetCityListStrategy{

    /**
     * Redis缓存服务对象
     */
    @Autowired
    private RedisService redisService;

    /**
     * 本地缓存服务对象
     */
    @Autowired
    private Cache<String, Object> caffeineCache;

    /**
     * 数据库查询策略对象
     */
    @Autowired
    private FromDBStrategy fromDBStrategy;


    /**
     * 城市列表查询 V3 二级缓存方案
     * @return 城市列表信息
     */
    @Override
    public List<SysRegionDTO> getCityList() {
        // 1 先查询两级缓存
        List<SysRegionDTO> cache = CacheUtil.getL2Cache(redisService, MapConstants.CACHE_MAP_CITY_KEY, new TypeReference<List<SysRegionDTO>>() {
        }, caffeineCache);
        if (cache != null) {
            return cache;
        }
        // 2 两级缓存未命中，查数据库，把城市摘出来
        List<SysRegionDTO> result = fromDBStrategy.getCityList();
        // 3 载入两级缓存
        CacheUtil.setL2Cache(redisService, MapConstants.CACHE_MAP_CITY_KEY, result, caffeineCache, 120L, TimeUnit.MINUTES);
        return result;
    }
    /**
     * 按首字母A-Z分类的城市列表查询 V3 二级缓存方案
     * @return 城市字母与城市列表的哈希
     */
    @Override
    public Map<String, List<SysRegionDTO>> getCityPyList() {
        // 1 先查询两级缓存
        Map<String, List<SysRegionDTO>> cache = CacheUtil.getL2Cache(redisService, MapConstants.CACHE_MAP_CITY_PINYIN_KEY, new TypeReference<Map<String, List<SysRegionDTO>>>() {
        }, caffeineCache);
        if (cache != null) {
            return cache;
        }
        // 2 两级缓存未命中，查数据库，把城市摘出来
        Map<String, List<SysRegionDTO>> result = fromDBStrategy.getCityPyList();
        // 3 载入两级缓存
        CacheUtil.setL2Cache(redisService, MapConstants.CACHE_MAP_CITY_PINYIN_KEY, result, caffeineCache, 120L, TimeUnit.MINUTES);
        return result;
    }
}
